//-----------------------------------------------------------------
// 功能描述:
//     HD44780(KS0066U)内核的字符型LCM子程序
// 硬件连接:
//     RS   	PD0			D4		PD4
//     RW		PD1			D5		PD5
//     E		PD2			D6		PD6
//                         D7		PD7
//-----------------------------------------------------------------

//-----------------------------------------------------------------
// 头文件包含
//-----------------------------------------------------------------
#include <stm32f10x.h>
#include "Delay.h"
#include "CharLCD.h"

//-----------------------------------------------------------------
// 全局变量:用RAM存储的单元数据
//-----------------------------------------------------------------
u8 lcdbuff;
u8 lcdbuff_1;

//-----------------------------------------------------------------
// 初始化程序段
//-----------------------------------------------------------------

//-----------------------------------------------------------------
// void LCM_Init (void)
//-----------------------------------------------------------------
//
// 功能描述: LCM初始化
// 输入参数: 无
// 返回参数: 无
// 全局变量: 无
// 调用模块: WrCLcdC(u8);CG_Write()     
//-----------------------------------------------------------------
void LCM_Init (void)
{
	u8 i;
	
	Delay_50ms(10);									// 延时等待液晶稳定		
	GPIO_LCM_Configuration();				// 液晶IO口初始化
	for (i=5; i>0; i--)
	{
		WrCLcdC(0x28);						   	// LCM工作方式:4位数据接口,2行5*7显示
	}
	WrCLcdC(0x01);						      // LCM清屏
	WrCLcdC(0x06);						      // LCM输入方式设置:写入数据后AC加1
	WrCLcdC(0x0F);						      // LCM显示状态设置:开,光标闪烁显示
	WrCLcdC(0x0C);						      // LCM显示状态设置:开显示
}

//-----------------------------------------------------------------
// void GPIO_LCM_Configuration(void)
//-----------------------------------------------------------------
//
// 功能描述: LCM IO配置
// 输入参数: 无
// 返回参数: 无
// 全局变量: 无
// 调用模块: RCC_APB2PeriphClockCmd();GPIO_Init();   
//-----------------------------------------------------------------
void GPIO_LCM_Configuration(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;

	// 使能时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);  
	// 									     	        RS		   		RW			  		E			    		 
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 
	//									D4						D5					D6						D7
								  | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6| GPIO_Pin_7;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_Init(GPIOD, &GPIO_InitStructure);
}
//-----------------------------------------------------------------
// 功能程序段
//-----------------------------------------------------------------

//-----------------------------------------------------------------
// void WrCLcdC (u8 lcdcomm)
//-----------------------------------------------------------------
//
// 功能描述: 写LCM的指令代码
// 输入参数: LCM指令
// 返回参数: 无
// 全局变量: lcdbuff:LCM命令/数据存储单元,按位操作
// 调用模块: Wr_CodeData()     
//-----------------------------------------------------------------
void WrCLcdC (u8 lcdcomm)
{
  lcdbuff = lcdcomm;
	lcdbuff_1 = lcdcomm;
	LCM_RS_clr;                             	// RS=0,RW=0,E=1-0:命令写
	LCM_RW_clr;
	Wr_CodeData();                      			// 写入LCM指令                             
}

//-----------------------------------------------------------------
// void WrCLcdD (u8 lcddata)
//-----------------------------------------------------------------
//
// 功能描述: 写LCM要显示的数据
// 输入参数: 待写入数据
// 返回参数: 无
// 全局变量: lcdbuff:LCM命令/数据存储单元,按位操作
// 调用模块: Wr_CodeData()     
//-----------------------------------------------------------------
void WrCLcdD (u8 lcddata)
{
  lcdbuff = lcddata;
	lcdbuff_1 = lcddata;
	LCM_RS_set;                             
	LCM_RW_clr;	
	Wr_CodeData();
}

//-----------------------------------------------------------------
// void WriteString (u8 x, u8 y, u8 *s)
//-----------------------------------------------------------------
//
// 功能描述: 指定位置显示一个字符串
// 输入参数: x:行, y:列, *s:字符指针
// 返回参数: 无
// 全局变量: 无
// 调用模块: WrCLcdC(u8);WrCLcdD(u8)     
// 注意事项: x的值只能为1或2, y≤16
//-----------------------------------------------------------------
void WriteString (u8 x, u8 y, u8 *s)          
{
	// 设置LCM显示DDRAM起始地址
  if (x == 1)
		WrCLcdC(0x80+y-0x01);										// 第一行
	else 
		WrCLcdC(0xc0+y-0x01);										// 第二行
	// 显示字符串					      	
	for ( ; *s != '\0'; s ++)
	{
		WrCLcdD (*s);	
	}	
}


//-----------------------------------------------------------------
// void Wr_CodeData (void)
//-----------------------------------------------------------------
//
// 功能描述: 写命令和数据共用子程序
// 输入参数: 无 
// 返回参数: 无
// 全局变量: 无
// 调用模块: 无     
//-----------------------------------------------------------------
 void Wr_CodeData (void)
{	
	// 写高半字节
	GPIOD->ODR &= 0Xff0f;											// 清数据位
	lcdbuff &= 0xf0;        									// 保留高位
	GPIOD->ODR |= lcdbuff;
	Delay_ns(1);
	LCM_E_set;                            		// E高低电平时间不能为450ns
	Delay_ns(1);															// 两次写入间隔太短会导致显示错误
	LCM_E_clr;                            		// E高低电平时间不能为450ns
	Delay_ns(1);
	// 写低半字节
	GPIOD->ODR &= 0xff0f;
	lcdbuff_1 &= 0x0f;
	lcdbuff_1 <<= 4;
	GPIOD->ODR |= lcdbuff_1;
	Delay_ns(1);
	LCM_E_set;                            	 
	Delay_ns(1);
	LCM_E_clr;                            	 
	Delay_1ms(5);
}

//-----------------------------------------------------------------
// End Of File
//-----------------------------------------------------------------